﻿namespace Webinator.Impls
{
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Drawing;
    using System.Linq;
    using Toolboxes;
    using Util;

    using Webinator.Interfaces;

    /// <summary>
    /// Common manager routines.
    /// </summary>
    [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "Reviewed. Suppression is OK here.")]
    internal class OperatingSystemDomain : IOperatingSystemDomain
    {
        private readonly ICore _core;

        private Process _process;

        public OperatingSystemDomain(ICore core)
        {
            _core = core;
        }

        public Process Process
        {
            get { return _process ?? (_process = GetProcess()); }
        }

        public Point GetViewportCoordinates()
        {
            var colors = new List<Color>();
            for (var i = 0; i < 100; i++)
            {
                colors.Add(Randomator.GetRandomColor());
            }

            var html = "<table border='0' cellspacing='0' cellpadding='0' style='position: absolute; left: 0px; top: 0px;'><tr height='1'>";
            foreach (var color in colors)
            {
                html += string.Format("<td width='1' bgcolor='{0}'></td>", ColorTranslator.ToHtml(color));
            }

            html += "</tr></table>";

            /* This won't work with IE6 unless a style hack is implemented
                * see: http://www.cssplay.co.uk/layouts/fixed.html
                * or: http://www.howtocreate.co.uk/fixedPosition.html
            */
            var addPixelCode = "var barcodeDiv=document.createElement('div');" +
                                "barcodeDiv.style.position='fixed';" +
                                "barcodeDiv.style.height='1px';" +
                                "barcodeDiv.style.top='0px';" +
                                "barcodeDiv.style.left='0px';" +
                                "barcodeDiv.id='WebinatorPixelCode';" +
                                string.Format(@"barcodeDiv.style.width='{0}px';", colors.Count) +
                                "barcodeDiv.style.zIndex=99999;" +
                                string.Format(@"barcodeDiv.innerHTML=""{0}"";", html) +
                                "document.getElementsByTagName('body')[0].appendChild(barcodeDiv);";

            const string RemovePixelCode = @"{var temp=document.getElementById('WebinatorPixelCode'); temp.parentNode.removeChild(temp);}";
            this._core.ExecuteScript(addPixelCode);
            var bp = new BitmapParser();
            Bitmap bitmap = bp.GetScreenshotOfWindow(Process.MainWindowHandle);
            Point point = bp.GetXyOfPattern(bitmap, colors.ToArray());
            this._core.ExecuteScript(RemovePixelCode);

            return point;
        }

        private Process GetProcess()
        {
            var oldTitle = (string)this._core.EvaluateScript("return document.title;");
            var newTitle = Randomator.RandomAlphanumeric(10);
            _core.ExecuteScript(string.Format("document.title = '{0}';", newTitle));
            Process process = null;
            bool success = false;

            while (!success)
            {
                try
                {
                    process = Process.GetProcesses().First(p => p.MainWindowTitle.Contains(newTitle));
                    success = true;
                }
                catch
                {
                }
            }

            this._core.ExecuteScript(string.Format("document.title = '{0}';", oldTitle));
            return process;
        }

        public WindowHelper.WindowState GetWindowState()
        {
            return WindowHelper.GetWindowState(Process.MainWindowHandle);
        }

        public void MaximizeWindow()
        {
            WindowHelper.MaximizeWindow(Process.MainWindowHandle);
        }
    }
}
